package com.bwie.es.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bwie.common.domain.Book;
import com.bwie.common.domain.request.BookRequest;
import com.bwie.common.result.PageResult;
import com.bwie.common.result.Result;
import com.bwie.common.utils.StringUtils;
import com.bwie.es.service.EsBookService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

@Service
public class EsBookServiceImpl implements EsBookService {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private HttpServletRequest request;

    public static  final String INDEX_NAME="book";


    @Override
    public Result<PageResult<Book>> searchBook(BookRequest bookRequest) {
        long total=0;
        ArrayList<Book> books = new ArrayList<>();

        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        if(StringUtils.isNotEmpty(bookRequest.getBookName())){
            boolQuery.must(QueryBuilders.matchQuery("bookName",bookRequest.getBookName()));
        }
        if(StringUtils.isNotEmpty(bookRequest.getBookAuthor())){
            boolQuery.must(QueryBuilders.matchQuery("bookAuthor",bookRequest.getBookAuthor()));
        }
        if(null!=bookRequest.getStartBookOriginalPrice()){
            boolQuery.should(QueryBuilders.rangeQuery("bookOriginalPrice").gte(bookRequest.getStartBookOriginalPrice()));
        }

        if(null!=bookRequest.getEndBookOriginalPrice()){
            boolQuery.should(QueryBuilders.rangeQuery("bookOriginalPrice").lte(bookRequest.getEndBookOriginalPrice()));
        }
        searchSourceBuilder.query(boolQuery);
        searchSourceBuilder.from((bookRequest.getPageNum()-1)*bookRequest.getPageSize());
        searchSourceBuilder.size(bookRequest.getPageSize());
        searchSourceBuilder.sort("bookMemberPrice", SortOrder.DESC);

        HighlightBuilder highlightBuilder = new HighlightBuilder().field("bookName").preTags("<font color:'blue'>").postTags("</font>");

        searchSourceBuilder.highlighter(highlightBuilder);
        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits searchHits = searchResponse.getHits();
             total = searchHits.getTotalHits().value;

            SearchHit[] hits = searchHits.getHits();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                Book book = JSONObject.parseObject(sourceAsString, Book.class);
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if(null!=highlightFields){
                    HighlightField highlightField = highlightFields.get("bookName");
                    if(null!=highlightField){
                        Text[] fragments = highlightField.getFragments();

                        StringBuffer sb = new StringBuffer();
                        for (Text fragment : fragments) {
                            sb.append(fragment);
                        }
                        book.setBookName(sb.toString());
                    }
                }
                books.add(book);

            }

        } catch (IOException e) {
           throw new RuntimeException("Es查询失败");
        }
        return PageResult.toResult(total,books);

    }
}

















